package com.atguigu.test;

import com.atguigu.aop.MathCalculator;
import com.atguigu.bean.Blue;
import com.atguigu.config.ExtConfig;
import com.atguigu.config.MainConfigAop;
import com.atguigu.ext.MyEvent;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.ApplicationEventMulticaster;

/**
 * bean创建的过程小结:
 *  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
 *  refresh();
 *  {
 * 			// 创建bean工厂Tell the subclass to refresh the internal bean factory.
 * 			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 *
 * 			// bean工厂初始化挂接一些通用的后置处理器和解析器-Prepare the bean factory for use in this context.
 * 			prepareBeanFactory(beanFactory);
 *
* 			//beanPost创建 Allows post-processing of the bean factory in context subclasses.
* 			postProcessBeanFactory(beanFactory);
*
* 			// Invoke factory processors registered as beans in the context.
* 			invokeBeanFactoryPostProcessors(beanFactory);
*
* 			//beanPost 注册 Register bean processors that intercept bean creation.
* 			registerBeanPostProcessors(beanFactory);
*
* 			//应用事件广播器创建 Initialize event multicaster for this context.
* 			initApplicationEventMulticaster();
*
* 			// Initialize other special beans in specific context subclasses.
* 			onRefresh();
*
* 			// 对于class中标记 ApplicationListener.class 注册到广播器中去
* 			registerListeners();
*
* 			// 初始化单例对象-Instantiate all remaining (non-lazy-init) singletons.
* 			finishBeanFactoryInitialization(beanFactory);
 * 		    {
 * 		        preInstantiateSingletons--初始化创建bean
 * 		        --  for (String beanName : beanNames) --Trigger initialization of all non-lazy singleton beans...
     * 		        {
     * 		             getBean(beanName);----1-bean创建 2-属性赋值 3-应用了一些
 * 		                 ----doGetBean
 *
     * 		         }
 *
 * 		             对所有的bean如果实现了SmartInitializingSingleton 那就进行调用
 * 		             for (String beanName : beanNames)
 * 		             {
 * 		                 if (singletonInstance instanceof SmartInitializingSingleton){
 * 		                     smartSingleton.afterSingletonsInstantiated();
 * 		                 }
 * 		             }
 *
 * 		    }
*
* 			// 发布容器刷新事件new ContextRefreshedEvent 事件-Last step: publish corresponding event.
* 			finishRefresh();
 *  }
 *
 * ---doGetBean
 * {
 *    // 当前bean依赖的bean先要进行初始化- Guarantee initialization of beans that the current bean depends on.
*     String[] dependsOn = mbd.getDependsOn();
*     if (dependsOn != null) {
*     	for (String dep : dependsOn) {
*     		registerDependentBean(dep, beanName);
*     		getBean(dep);*                }
*     }
 *
 *    // Create bean instance.
 * 	 if (mbd.isSingleton()) {
 * 	 	----createBean(beanName, mbd, args)
 * 	      1: creates a bean instance, 2:populates the bean instance 3:	applies post-processors
 * 	      {
 * 	          1: 对于 InstantiationAwareBeanPostProcessor的后置处理器如果有代理的可以进行代理
 * 	          // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
 * 			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
 * 			if (bean != null) {
 * 				return bean;
 *           }
 * 	         doCreateBean--核心方法--如果没有被代理开始真正创建对应的beanActually create the specified bean. Pre-creation processing has already happened at this point
 * 	         {
 * 	             //利用反射创建实例
 * 	             instanceWrapper = createBeanInstance(beanName, mbd, args);
 * 	             // 应用后置处理器[@link MergedBeanDefinitionPostProcessor] 进行处理Allow post-processors to modify the merged bean definition.
 * 	             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 * 	             {
 * 	               for (BeanPostProcessor bp : getBeanPostProcessors()) {
 * 			            if (bp instanceof MergedBeanDefinitionPostProcessor) {
 * 				            bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
 *                      }
 * 	              }
 * 	            }
 *
 * 	            //进行属性赋值
 * 	            populateBean(beanName, mbd, instanceWrapper);
 *
 * 	            //初始化实例Initialize the given bean instance, applying factory callbacks as well as init methods and bean post processors.
 * 	            initializeBean(beanName, exposedObject, mbd);
 * 	            {
 * 	               //初始化以前的前置处理器
 * 	                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * 	                //调用初始化方法
 * 	                invokeInitMethods(beanName, wrappedBean, mbd);
 * 	                //调用后置处理器
 * 	                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 * 	            }
 *
 * 	      }
 *
 * }
 */
public class IOCTest_Ext {

    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
        Blue bean = applicationContext.getBean(Blue.class);
        ApplicationEventMulticaster multicaster = applicationContext.getBean(ApplicationEventMulticaster.class);
        System.out.println(multicaster);
        MyEvent myEvent = new MyEvent(new Blue());
        multicaster.multicastEvent(myEvent);
        applicationContext.publishEvent(myEvent);
        System.out.println("----");
        applicationContext.close();
        System.out.println(bean);
    }
}
